package com.landun.market.util;


import java.math.BigDecimal;

/**
 * @author chuan.jiang
 * @since 2017-08-17
 */
public class FinanceUtils {
    // 转换比例(以元为单位进行比例转换，精确到分后面3位有效)
    private static long PRICE_RATIO = 10 * 10 * 1000L;

    // 转换比例(以分为单位进行比例转换，精确到分后面3位有效)
    private static long PRICE_RATIO_FEN = 1000L;

    // 除法精确位数
    private static int BIGDECIMAL_SCALE = 10;

    // 金额单位分保留位数
    private static int BIGDECIMAL_FEN_SCALE = 0;

    // 金额单位元保留位数
    private static int BIGDECIMAL_YUAN_SCALE = 2;

    //  小数扩大10的10次方倍
    private static long BIGDECIMAL_DECIMALS = 1000 * 1000 * 1000 * 10L;

    //  百分数扩大10的8次方倍
    private static long BIGDECIMAL_PERCENT = 1000 * 1000 * 100L;

    /**
     * 将数据库里面的价格转换到以元为单位
     *
     * @param price 需要转换的价格
     * @return 返回以元为单位的字符串
     */
    public static String convertToYuan(Long price) {

        if (NumberUtils.isNull(price)) {
            return StringUtils.EMPTY;
        }
        if (price.intValue() == 0) {
            return "0";
        }
        return removeZero(convertToBigDecimal(price, AmountUnit.Yuan).toString());
    }


    /**
     * 去掉小数点后面的0
     *
     * @param s
     * @return
     */
    public static String removeZero(String s) {
        if (null == s || s.isEmpty()) {
            return "";
        }
        if (s.indexOf(".") > 0) {
            s = s.replaceAll("0+?$", "");//去掉多余的0
            s = s.replaceAll("[.]$", "");//如最后一位是.则去掉
        }
        return s;
    }


    /**
     * 将数据库里面的价格转换到分单位
     *
     * @param price 需要转换的价格
     * @return 返回以元为单位的字符串
     */
    public static String convertToFen(Long price) {

        if (NumberUtils.isNull(price)) {
            return StringUtils.EMPTY;
        }
        if (price.intValue() == 0) {
            return "0";
        }
        return convertToBigDecimal(price, AmountUnit.Fen).toString();
    }

    /**
     * 将外部元的金额转换成 Long的数据
     *
     * @param strPrice 字符串的价格
     * @return 返回以 Long 型的金额
     */
    public static Long priceYuanToLong(String strPrice) {

        if (StringUtils.isEmpty(strPrice)) {
            return null;
        }
        try {
            BigDecimal price = ConvertUtils.toBigDecimal(strPrice, null);
            if (null == price) {
                return 0L;
            }
            return price.multiply(BigDecimal.valueOf(PRICE_RATIO)).longValue();
        } catch (Exception ex) {
            return null;
        }
    }


    /**
     * 将外部分的金额转换成 Long的数据
     *
     * @param strPrice
     * @return
     */
    public static Long priceFenToLong(String strPrice) {

        if (StringUtils.isEmpty(strPrice)) {
            return null;
        }
        try {
            BigDecimal price = ConvertUtils.toBigDecimal(strPrice, null);
            if (null == price) {
                return 0L;
            }
            return price.multiply(BigDecimal.valueOf(PRICE_RATIO_FEN)).longValue();
        } catch (Exception ex) {
            return null;
        }
    }

    public static Long getSysPrice(String amount) {
        return Long.valueOf(changeY2F(amount)) * 1000;
    }

    /**
     * 将元为单位的转换为分 替换小数点，支持以逗号区分的金额
     *
     * @param amount
     * @return
     */
    public static String changeY2F(String amount) {
        String currency = amount.replaceAll("\\$|\\￥|\\,", "");  //处理包含, ￥ 或者$的金额
        int index = currency.indexOf(".");
        int length = currency.length();
        Long amLong = 0l;
        if (index == -1) {
            amLong = Long.valueOf(currency + "00");
        } else if (length - index >= 3) {
            amLong = Long.valueOf((currency.substring(0, index + 3)).replace(".", ""));
        } else if (length - index == 2) {
            amLong = Long.valueOf((currency.substring(0, index + 2)).replace(".", "") + 0);
        } else {
            amLong = Long.valueOf((currency.substring(0, index + 1)).replace(".", "") + "00");
        }
        return amLong.toString();
    }


    /**
     * 将数据库中long类型的金额 转化为分 元 等单位
     *
     * @param price
     * @return
     */
    public static BigDecimal convertToBigDecimal(Long price, AmountUnit unit) {
        BigDecimal result = BigDecimal.ZERO;

        if (null != price && price == 0) {
            return result;
        }

        if (NumberUtils.isNotPositive(price)) {
            return result;
        }
        try {
            switch (unit) {
            case Fen:
                result = (new BigDecimal(price).divide(BigDecimal.valueOf(PRICE_RATIO_FEN), BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP))
                        .setScale(BIGDECIMAL_FEN_SCALE, BigDecimal.ROUND_HALF_UP);
                break;
            case Yuan:
                result = (new BigDecimal(price).divide(BigDecimal.valueOf(PRICE_RATIO), BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP))
                        .setScale(BIGDECIMAL_YUAN_SCALE, BigDecimal.ROUND_HALF_UP);
                break;
            default:
            }
            return result;
        } catch (Exception ex) {
            return BigDecimal.ZERO;
        }
    }

    public static BigDecimal convertToBigDecimalIncludeNegative(Long price, AmountUnit unit) {
        BigDecimal result = BigDecimal.ZERO;

        if (null != price && price == 0) {
            return result;
        }

        try {
            switch (unit) {
            case Fen:
                result = (new BigDecimal(price).divide(BigDecimal.valueOf(PRICE_RATIO_FEN), BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP))
                        .setScale(BIGDECIMAL_FEN_SCALE, BigDecimal.ROUND_HALF_UP);
                break;
            case Yuan:
                result = (new BigDecimal(price).divide(BigDecimal.valueOf(PRICE_RATIO), BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP))
                        .setScale(BIGDECIMAL_YUAN_SCALE, BigDecimal.ROUND_HALF_UP);
                break;
            default:
            }
            return result;
        } catch (Exception ex) {
            return BigDecimal.ZERO;
        }
    }

    /**
     * 百分比转为系统存储的Long
     *
     * @param percent 百分数,实际比传入的要小100倍，因为这里没带百分号
     * @return
     */
    public static Long percentToSysLong(String percent) {
        if (StringUtils.isEmpty(percent)) {
            return null;
        }
        try {
            BigDecimal percentDecimal = ConvertUtils.toBigDecimal(percent, null);
            if (null == percentDecimal) {
                return 0L;
            }
            return percentDecimal.multiply(BigDecimal.valueOf(BIGDECIMAL_PERCENT)).longValue();
        } catch (Exception ex) {
            return null;
        }
    }

    /**
     * long装换为百分数
     *
     * @param percentNumber
     * @return
     */
    public static String longToPercent(Long percentNumber) {
        if (NumberUtils.isNotPositive(percentNumber)) {
            return "";
        }

        return new BigDecimal(percentNumber).divide(BigDecimal.valueOf(BIGDECIMAL_PERCENT)).toString();
    }

    /**
     * long装换成小数
     *
     * @param percentNumber
     * @return
     */
    public static String longToDecimals(Long percentNumber) {
        if (NumberUtils.isNotPositive(percentNumber)) {
            return "";
        }

        return new BigDecimal(percentNumber).divide(BigDecimal.valueOf(BIGDECIMAL_DECIMALS)).toString();
    }

    /**
     * 计算作家店铺供货价，作者供应价=供货商供应价+（供货商供应价  x  n%），n=作者供应价百分比
     *
     * @param costPrice      供货商供应价
     * @param costPriceRatio 作家店铺供货价比例
     * @return 作家店铺供货价（如果向上取整）
     */
    public static Long getCostPriceAuthor(Long costPrice, Long costPriceRatio) {
        if (NumberUtils.isNotPositive(costPriceRatio) || NumberUtils.isNotPositive(costPrice)) {
            return costPrice;
        }
        BigDecimal costPriceAuthor = new BigDecimal(costPrice).multiply(
                BigDecimal.ONE.add(
                        new BigDecimal(costPriceRatio).divide(BigDecimal.valueOf(PRICE_RATIO * 100), BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP)
                )
        );
        BigDecimal costPriceAuthorYuan = (costPriceAuthor.divide(BigDecimal.valueOf(PRICE_RATIO), BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP)).setScale(BIGDECIMAL_YUAN_SCALE, BigDecimal.ROUND_HALF_UP);
        double ceil = Math.ceil(costPriceAuthorYuan.doubleValue());
        return new Double(ceil).longValue() * PRICE_RATIO;
    }
}
